package com.sgcc.pda.hzaidl.impl;

import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.sgcc.pda.data.dao.SharepreferenceUtil;
import com.sgcc.pda.hzaidl.AIDLServiceImpl;
import com.sgcc.pda.hzaidl.IHZAidl;
import com.sgcc.pda.hzaidl.IHZAidlCallback;
import com.sgcc.pda.hzaidl.entity.DownloadProgressBean;
import com.sgcc.pda.hzaidl.entity.RequestBean;
import com.sgcc.pda.hzaidl.entity.ResponseBean;
import com.sgcc.pda.tools.JsonUtils;
import com.sgcc.pda.tools.LogPrintUtils;
import com.sgcc.pda.util.DataConversionUtil;
import com.sgcc.pda.util.PlatConstant;
import com.sgcc.pda.web.receiver.IWebCall;
import com.sgcc.platforminterface.PlatfInterfManager;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @创建者：suven on 2019/12/16 15:18
 * @描述：
 * @版本：1.0
 * @修改人：
 * @修改时间：
 * @修改说明：
 * @修改版本：
 */
public class SpeedWebUtil {


    private static IHZAidl mHZAidl;

    private static AIDLServiceImpl getWebManager() {
        return AIDLServiceImpl.getInstance();
    }


    /**
     * 请求数据
     *
     * @param serverName    服务名
     * @param url
     * @param cmdName       接口名（路径）
     * @param requestParams 参数
     * @   错误
     */
    public static void postData(String serverName, String url, String cmdName, Map<String, String> requestParams, IWebCall iWebCall)    {
        postData(url, weaveString(serverName, cmdName, requestParams), iWebCall);
    }

    /**
     * 请求数据
     *
     * @param serverName    服务名
     * @param url
     * @param cmdName       接口名（路径）
     * @param requestParams 参数
     * @   错误
     */
    public static void postData(String serverName, String url, String cmdName, Map<String, String> requestParams, boolean appendUid, IWebCall iWebCall)    {
        postData(url, appendUid ? weaveString(serverName, cmdName, requestParams) : weaveStringOld(serverName, cmdName, requestParams), iWebCall);
    }

    /**
     * 上传图文
     *
     * @param serverName    服务名
     * @param cmdName       接口名（包含路径）
     * @param requestParams 参数
     * @param files         文件列表
     * @   错误
     */
    public static void uploadPramsAndFiles(String serverName, String cmdName, Map<String, String> requestParams, List<File> files, IWebCall iWebCall)    {
        if (files != null && !files.isEmpty()) {
            uploadPramsAndFiles(serverName, PlatConstant.IWeb.REQ_HTTP_FILES, cmdName, requestParams, files, iWebCall);
        } else {
            postData(serverName, PlatConstant.IWeb.REQ_HTTP_FILES, cmdName, requestParams, iWebCall);
        }
    }

    /**
     * 上传图文
     *
     * @param serverName    服务名
     * @param cmdName       接口名（包含路径）
     * @param requestParams 参数
     * @param files         文件列表
     * @param appendUid     是否拼接Uid
     * @   错误
     */
    public static void uploadPramsAndFiles(String serverName, String cmdName, Map<String, String> requestParams, List<File> files, boolean appendUid, IWebCall iWebCall)    {
        if (files != null && !files.isEmpty()) {
            uploadPramsAndFiles(serverName, PlatConstant.IWeb.REQ_HTTP_FILES, cmdName, requestParams, files, appendUid, iWebCall);
        } else {
            postData(serverName, PlatConstant.IWeb.REQ_HTTP_FILES, cmdName, requestParams, appendUid, iWebCall);
        }
    }

    /**
     * 上传图文
     *
     * @param serverName    服务名
     * @param url
     * @param cmdName       接口名（包含路径）
     * @param requestParams 参数
     * @param files         文件列表
     * @   错误
     */
    protected static void uploadPramsAndFiles(String serverName, String url, String cmdName, Map<String, String> requestParams, List<File> files, IWebCall iWebCall)
               {
        uploadFile(url, weaveString(serverName, cmdName, requestParams), onFilesToString(files), iWebCall);
    }

    /**
     * 上传图文
     *
     * @param serverName    服务名
     * @param url
     * @param cmdName       接口名（包含路径）
     * @param requestParams 参数
     * @param files         文件列表
     * @param appendUid     是否拼接Uid
     * @   错误
     */
    protected static void uploadPramsAndFiles(String serverName, String url, String cmdName, Map<String, String> requestParams, List<File> files, boolean appendUid, IWebCall iWebCall) {
        uploadFile(url, appendUid ? weaveString(serverName, cmdName, requestParams) : weaveStringOld(serverName, cmdName, requestParams), onFilesToString(files), iWebCall);
    }

    /**
     * 上传图文
     *
     * @param app_no   工单编号
     * @param app_type 工单类型
     * @param imgs     图片信息
     * @param files    图片列表
     * @   错误
     */
    public static void uploadImg(String app_no,
                                 String app_type, String imgs, List<File> files, IWebCall iWebCall)
               {
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put(PlatConstant.IWeb.UID, SharepreferenceUtil.getUid(PlatfInterfManager.getInstance().getContext()));
        requestParams.put("APP_NO", app_no);
        requestParams.put("APP_TYPE", app_type);
        requestParams.put("IMGS", imgs);
        requestParams.put(PlatConstant.IWeb.MAC, SharepreferenceUtil.getMac(PlatfInterfManager.getInstance().getContext()));
        uploadPramsAndFiles(PlatConstant.IWeb.UPFILESERVER, PlatConstant.IWeb.REQ_HTTP_FILE_UP, "upFile.do?", requestParams, files, iWebCall);
    }

    /**
     * 文件下载
     *
     * @param serverName    服务名
     * @param cmdName       方法名
     * @param requestParams 请求参数
     * @param filePath      保存路+文件名
     * @param fileName      文件名
     * @param iWebCall      回调
     * @   异常返回
     */
    public static void download(String serverName, String cmdName, Map<String, String> requestParams, String filePath, String fileName, IWebCall iWebCall)    {
        download(PlatConstant.IWeb.REQ_HTTP_FILE_DOWN, serverName, cmdName, requestParams, filePath, fileName, iWebCall);
    }

    /**
     * 文件下载
     *
     * @param methodName    方法名
     * @param serverName    服务名
     * @param cmdName       方法名
     * @param requestParams 请求参数
     * @param filePath      保存路+文件名
     * @param fileName      文件名
     * @param iWebCall      回调
     * @   异常返回
     */
    public static void download(String methodName, String serverName, String cmdName, Map<String, String> requestParams, String filePath, String fileName, IWebCall iWebCall)    {
        download(getDownloadUrl(methodName, serverName, cmdName, requestParams), filePath, fileName, iWebCall);
    }

    /**
     * 下载文件
     *
     * @param url
     * @param filePath 本地保存路径
     * @param fileName 本地保存文件名
     * @   错误
     */
    protected static void download(String url, String filePath, String fileName, IWebCall iWebCall)    {
        downloadFile(url, filePath, fileName, iWebCall);
    }

    /**
     * Post请求
     *
     * @param url
     * @param requestParams
     * @param iWebCall
     * @  
     */
    protected static void postData(String url, String requestParams, IWebCall iWebCall)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("uri", url);
            jb.put("requestParams", requestParams);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        requestData("postDataCallback", jb.toString(), iWebCall);
    }


    /**
     * 上传图文
     *
     * @param url
     * @param requestParams
     * @param filePath
     * @param iWebCall
     * @  
     */
    protected static void uploadFile(String url, String requestParams, String filePath, IWebCall iWebCall)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("uri", url);
            jb.put("requestParams", requestParams);
            jb.put("filePath", filePath);
            //上传日志是“file”图文上传时“files”,上传图片是“uploadfiles”
            jb.put("fileKey", "files");
        } catch (JSONException e) {
            e.printStackTrace();
            LogPrintUtils.d("uploadFile", e);
        }
        LogPrintUtils.d(String.format("uploadFile:%s", jb.toString()));
        requestData("uploadFile", jb.toString(), iWebCall);
    }


    /**
     * 下载文件
     *
     * @param url
     * @param filePath
     * @param fileName
     * @param iWebCall
     * @  
     */
    protected static void downloadFile(String url, String filePath, String fileName, IWebCall iWebCall)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("uri", url);
            jb.put("filePath", filePath);
            jb.put("fileName", fileName);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        requestData("downloadFile", jb.toString(), iWebCall);
    }


    /**
     * 订阅一个主题，后台根据主题推送消息
     */
    public static boolean subscribe(String packageName, String topic)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("packageName", packageName);
            jb.put("topic", topic);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            JSONObject msgJson = requestDataJsObject("subscribe", jb.toString());
            return msgJson != null && msgJson.getBoolean("success");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 向对应的主题，发布一条消息。
     * topic  主题名
     * content 发布的内容
     */
    public static boolean publish(String topic, String content)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("topic", topic);
            jb.put("content", content);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            JSONObject msgJson = requestDataJsObject("publish", jb.toString());
            return msgJson != null && msgJson.getBoolean("success");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 取消订阅一个主题
     */
    public static boolean unsubscribe(String packageName, String topic)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("packageName", packageName);
            jb.put("topic", topic);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            JSONObject msgJson = requestDataJsObject("unsubscribe", jb.toString());
            return msgJson != null && msgJson.getBoolean("success");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取离线消息
     * packageName 包名
     */
    public static String getOfflineMsg(String packageName)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("packageName", packageName);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return requestData("getOfflineMsg", jb.toString());
    }

    /**
     * 上报已收到消息
     * packageName  包名
     * time 时间戳tag
     */
    public static boolean reportReceivedMsg(String packageName, String time)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("packageName", packageName);
            jb.put("time", time);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            JSONObject msgJson = requestDataJsObject("reportReceivedMsg", jb.toString());
            return msgJson != null && msgJson.getBoolean("success");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 大文件上传
     *
     * @param filePath 上传文件路径
     * @param savePath 服务器保存路径
     * @param isDelete 是否删除
     * @  
     */
    public static void blockUploadFile(String filePath, String savePath, boolean isDelete, IWebCall iWebCall)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("filePath", filePath);
            jb.put("savePath", savePath);
            jb.put("isDelete", isDelete);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        requestData("blockUploadFile", jb.toString(), iWebCall);
    }


    /**
     * 取消大文件上传
     *
     * @param filePath 上传文件路径
     * @param savePath 服务器保存路径
     * @param iWebCall
     * @  
     */
    public static void cancelBlockUploadFile(String filePath, String savePath, IWebCall iWebCall)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("filePath", filePath);
            jb.put("savePath", savePath);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        requestData("cancelBlockUploadFile", jb.toString(), iWebCall);
    }

    /**
     * 参数查询接口
     *
     * @param appIdentity  应用标识(APP包名或其它标识)
     * @param paramVersion 参数版本号 参数版本号（第一次可为空）
     * @param iWebCall     请求数据的回调
     */
    public static void getParamQuery(String appIdentity, String paramVersion, IWebCall iWebCall)    {
        JSONObject jb = new JSONObject();
        try {
            jb.put("appIdentity", appIdentity);
            jb.put("paramVersion", paramVersion);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        requestData("commParmUpdate", jb.toString(), iWebCall);
    }

    /**
     * 文件下载接口(支持多种文件，断点续传)
     *
     * @param filePath           图片在服务端的路径
     * @param savePath           图片在本地保存的路径
     * @param callback  请求数据的回调
     */
    public static void downPicFile(@NonNull String filePath, @NonNull String savePath, @Nullable IHZAidlCallback callback) {
        // 下载图片接口名称和参数
        String requestParams = "downPicFile?FILEPATH=" + filePath;
        LogPrintUtils.d("downloadPicFile", requestParams);

        // 下载服务名称和参数
        StringBuilder builder = new StringBuilder();
        builder.append("reqHttpFileDown.do").append("?SERVER_NAME=").append("upfileserver").append("&REQUEST_PARM=");
        builder.append(DataConversionUtil.str2HexStr(requestParams));
        builder.append("&UID=").append(SharepreferenceUtil.getUid(PlatfInterfManager.getInstance().getContext()));
        builder.append("&MAC=").append(SharepreferenceUtil.getMac(PlatfInterfManager.getInstance().getContext()));

        String url = builder.toString();
        LogPrintUtils.d("downloadPicFile", url);

        JSONObject jb = new JSONObject();
        try {
            jb.put("filePath", savePath);// 文件保存路径
            jb.put("uri", url);// 下载路径
            jb.put("type", 0);// 类型 0不适用进度条 1使用进度条
        } catch (JSONException e) {
            e.printStackTrace();
        }

        RequestBean requestData = new RequestBean();
        requestData.setMainCode("web");// 请求上行通讯
        requestData.setMethodName("downloadFile");// 调用下载接口
        requestData.setParamJson(jb.toString());
        requestData.setPackageName(PlatfInterfManager.getInstance().getContext().getPackageName());
        // 调用统一AIDL
        AIDLServiceImpl.getInstance().post(JsonUtils.toJson(requestData), callback);
    }

    /**
     * @param methodName 方法名
     * @param paramJson  参数列表
     */
    protected static JSONObject requestDataJsObject(String methodName, String paramJson) throws JSONException {
        RequestBean requestBean = new RequestBean(PlatConstant.IWebCmd.WEB, methodName, paramJson, PlatfInterfManager.getInstance().getPackageName(), "");
        String result = getWebManager().post(requestBean.toString(), null);
        ResponseBean responseBean = JsonUtils.toBean(result, ResponseBean.class);
        if (responseBean != null && responseBean.getRetCode() == 1) {
            return new JSONObject(responseBean.getMsgJson());
        } else {
            return null;
        }
    }

    protected static String requestData(String methodName, String paramJson)    {
        RequestBean requestBean = new RequestBean(PlatConstant.IWebCmd.WEB, methodName, paramJson, PlatfInterfManager.getInstance().getPackageName(), "");
        String result = getWebManager().post(requestBean.toString(), null);
        ResponseBean responseBean = JsonUtils.toBean(result, ResponseBean.class);
        if (responseBean != null && responseBean.getRetCode() == 1) {
            return responseBean.getMsgJson();
        } else {
            return null;
        }
    }

    /**
     * @param methodName 方法名
     * @param paramJson  参数列表
     */
    protected static void requestData(String methodName, String paramJson, IWebCall iWebCall)    {
        RequestBean requestBean = new RequestBean(PlatConstant.IWebCmd.WEB, methodName, paramJson, PlatfInterfManager.getInstance().getPackageName(), iWebCall == null ? "" : iWebCall.getTag());
        requestData(requestBean, iWebCall);
    }

    /**
     * @param requestBean 请求对像
     */
    private static void requestData(final RequestBean requestBean, final IWebCall iWebCall)  {
        try {
            if (iWebCall == null) {
                getWebManager().post(requestBean.toString(), null);
            } else
                getWebManager().post(requestBean.toString(), new IHZAidlCallback.Stub() {
                    @Override
                    public void callback(final String result)    {
                        Handler handler = new Handler(Looper.getMainLooper());
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    LogPrintUtils.d(result);
                                    if (TextUtils.isEmpty(result)) {
                                        //异常信息
                                        LogPrintUtils.d(String.format("接口信息返回为空 %s", PlatConstant.IWebState.none));
                                        iWebCall.onFail(PlatConstant.IWebState.none, "接口信息返回为空");
                                        return;
                                    }
                                    ResponseBean responseBean = JsonUtils.toBean(result, ResponseBean.class);
                                    if (responseBean != null) {
                                        //如果标识不为空则需要比对，返回不进行比对标识,如果标识是空，或者标识不为空等于返回标识则通过
                                        if (TextUtils.isEmpty(iWebCall.getTag()) || (!TextUtils.isEmpty(iWebCall.getTag()) && TextUtils.equals(responseBean.getTag(), iWebCall.getTag()))) {
                                            resolveBiz(responseBean, iWebCall);
                                        } else {
                                            LogPrintUtils.d(String.format("标识不匹配：请求标识，%s  返回标识，%s", iWebCall.getTag(), responseBean.getTag()));
                                            iWebCall.onFail(PlatConstant.IWebState.return_code_error, "接口返回错误");
                                        }
                                    } else {
                                        //异常信息
                                        LogPrintUtils.d(String.format("接口返回解析错误 %s", PlatConstant.IWebState.encrypterror));
                                        iWebCall.onFail(PlatConstant.IWebState.encrypterror, "接口返回解析错误");
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    LogPrintUtils.d(String.format("接口返回产生异常 %s", PlatConstant.IWebState.error));
                                    iWebCall.onFail(PlatConstant.IWebState.error, "接口返回产生异常");
                                }
                            }
                        });
                    }
                });
        } catch (Exception e) {
            e.printStackTrace();
            LogPrintUtils.d(String.format("接口调用产生异常 %s", PlatConstant.IWebState.error));
            iWebCall.onFail(PlatConstant.IWebState.error, "接口调用产生异常");
        }
    }


    /**
     * 结果解析
     *
     * @param responseBean 请求
     * @param iWebCall     返回
     */
    private static void resolveBiz(final ResponseBean responseBean, final IWebCall iWebCall) {
        switch (responseBean.getRetCode()) {
            case 1://成功
                iWebCall.onSuccess(responseBean.getMsgJson());
                break;
            case 2://过程
                try {
                    DownloadProgressBean downloadProgressBean = JsonUtils.toBean(responseBean.getMsgJson(), DownloadProgressBean.class);
                    if (downloadProgressBean != null) {
                        iWebCall.onDownLoading(downloadProgressBean.getCurrent(), downloadProgressBean.getTotal());
                    } else {
                        iWebCall.onFail(PlatConstant.IWebState.encrypterror, "进度解析解析错误");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LogPrintUtils.d(e);
                    iWebCall.onFail(PlatConstant.IWebState.error, "进度解析产生异常");
                }
                break;
            case 0://失败
            default:
                iWebCall.onFail(String.valueOf(responseBean.getRetCode()), responseBean.getMsgJson());
                break;
        }
    }


    private static String weaveString(String serverName, String cmdName, Map<String, String> requestParams) {
        Uri.Builder builder = Uri.parse(cmdName).buildUpon();
        for (String key : requestParams.keySet()) {
            builder.appendQueryParameter(key, requestParams.get(key));
        }
        LogPrintUtils.d("入参：", builder.toString());
        JSONObject jb = new JSONObject();
        try {
            String paramsHex = DataConversionUtil.str2HexStr(builder.toString());
            jb.put(PlatConstant.IWeb.SERVER_NAME, serverName);
            jb.put(PlatConstant.IWeb.REQUEST_PARM, paramsHex);
            jb.put(PlatConstant.IWeb.UID, SharepreferenceUtil.getUid(PlatfInterfManager.getInstance().getContext()));
            jb.put(PlatConstant.IWeb.MAC, SharepreferenceUtil.getMac(PlatfInterfManager.getInstance().getContext()));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jb.toString();
    }

    /**
     * 原来的weaveString没有添加uid和mac
     * @param serverName
     * @param cmdName
     * @param requestParams
     * @return
     */
    private static String weaveStringOld(String serverName, String cmdName, Map<String, String> requestParams) {
        Uri.Builder builder = Uri.parse(cmdName).buildUpon();
        for (String key : requestParams.keySet()) {
            builder.appendQueryParameter(key, requestParams.get(key));
        }
        LogPrintUtils.d("入参：", builder.toString());
        JSONObject jb = new JSONObject();
        try {
            String paramsHex = DataConversionUtil.str2HexStr(builder.toString());
            jb.put(PlatConstant.IWeb.SERVER_NAME, serverName);
            jb.put(PlatConstant.IWeb.REQUEST_PARM, paramsHex);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jb.toString();
    }

    /**
     * 获得请求前置URL
     *
     * @param serverName    服务名
     * @param cmdName       接口名（包含路径）
     * @param requestParams 参数
     * @return
     */
    public static String getDownloadUrl(String methodName, String serverName, String cmdName, Map<String, String> requestParams) {
        Uri.Builder builder = Uri.parse(cmdName).buildUpon();
        for (String key : requestParams.keySet()) {
            builder.appendQueryParameter(key, requestParams.get(key));
        }
        Map<String, String> urlParams = new HashMap<>();
        urlParams.put(PlatConstant.IWeb.SERVER_NAME, serverName);
        urlParams.put(PlatConstant.IWeb.REQUEST_PARM, DataConversionUtil.str2HexStr(builder.toString()));
        urlParams.put(PlatConstant.IWeb.UID, SharepreferenceUtil.getUid(PlatfInterfManager.getInstance().getContext()));
        urlParams.put(PlatConstant.IWeb.MAC, SharepreferenceUtil.getMac(PlatfInterfManager.getInstance().getContext()));
        Uri.Builder urlBuilder = Uri.parse(methodName).buildUpon();
        for (String key : urlParams.keySet()) {
            urlBuilder.appendQueryParameter(key, urlParams.get(key));
        }
        return urlBuilder.toString();
    }


    public static String onFilesToString(List<File> files) {
        StringBuilder paths = new StringBuilder();
        if (null != files) {
            for (File file : files) {
                paths.append(file.getAbsolutePath()).append(";");
            }
            int lastIndex = paths.lastIndexOf(";");
            if (lastIndex != -1) {
                paths.replace(lastIndex, lastIndex + 1, "");
            }
        }
        return paths.toString();
    }

}
